﻿@using Gurux.DLMS.AMI.Shared.DIs

@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@using Gurux.DLMS.AMI.Shared.DTOs.Authentication
@using Gurux.DLMS.AMI.Shared.DTOs
@using Gurux.DLMS.AMI.Shared.Rest
@using Gurux.DLMS.AMI.Shared.Enums
@using Gurux.DLMS.AMI.Client.Helpers
@using Gurux.DLMS.AMI.Module

@attribute [Authorize(Roles = "Admin, WorkflowManager")]
@inject NavigationManager NavigationManager
@inject HttpClient Http
@inject IGXNotifier2 Notifier

@if (Active != null && triggers != null)
{
    <EditForm Model="@Active">
        <DataAnnotationsValidator />
        <ValidationSummary />
        <div class="row">
            <div style="width:100%">
                <div class="form-group">
                    <InputNullableSwitch Text="@Properties.Resources.Active" @bind-Value="Active.Active" />
                    <br />
                </div>
                <div class="form-group">
                    <label>@Properties.Resources.Name</label>
                    <InputText id="name" disabled="@IsDeleting" class="form-control"
                           @bind-Value="Active.Name" />
                </div>
                <div class="form-group">
                    <label>@Properties.Resources.Description</label>
                    <InputText id="name" disabled="@IsDeleting" class="form-control"
                           @bind-Value="Active.Description" />
                </div>
                <div class="form-group">
                    <label>Trigger</label>
                    <select class="form-select" @bind="@SelectedTrigger">
                        @foreach (var it in triggers)
                        {
                            <option value="@it.ClassName">@it.Name</option>
                        }
                    </select>
                </div>
                <div class="form-group">
                    <label>Activities</label>
                    <select class="form-select" @bind="@SelectedActivity">
                        @foreach (var it in Activities)
                        {
                            <option value="@it.Name">@it.Name</option>
                        }
                    </select>
                </div>
                @if (_scriptMethods != null)
                {
                    <div class="form-group">
                        <label>Condition</label>
                        <select class="form-select" @bind="SelectedCondition">
                            @foreach (var it in _scriptMethods)
                            {
                                <option value="@it.Name">@it.Name</option>
                            }
                        </select>
                    </div>
                }
                @if (Active.CreationTime != null)
                {
                    <div class="form-group">
                        <label>@Properties.Resources.CreationTime</label>
                        <InputDate Type="@InputDateType.DateTimeLocal" id="generation" readonly="readonly" class="form-control"
                           @bind-Value="Active.CreationTime" />
                    </div>
                }
                @if (Active.Updated != null)
                {
                    <div class="form-group">
                        <label>@Properties.Resources.Updated</label>
                        <InputDate Type="@InputDateType.DateTimeLocal" id="generation" readonly="readonly" class="form-control"
                           @bind-Value="Active.Updated" />
                    </div>
                }
                @if (Active.Removed != null)
                {
                    <div class="form-group">
                        <label>@Properties.Resources.Removed</label>
                        <InputDate Type="@InputDateType.DateTimeLocal" id="removed" class="form-control"
                           @bind-Value="Active.Removed" />
                    </div>
                }
                @if (action == CrudAction.Delete)
                {
                    <hr />
                    <p>
                    </p>
                    <div class="form-group">
                        <InputRadioGroup @bind-Value="DeleteTarget">
                            <InputRadio Value="false">
                            </InputRadio>
                            <label>@Properties.Resources.TargetDisableQuestion</label><br>
                            <InputRadio Value="true">
                            </InputRadio>
                            <label>@Properties.Resources.TargetDeleteQuestion</label>
                        </InputRadioGroup>
                        <br />
                    </div>
                }
            </div>
        </div>
    </EditForm>
}
@code {
    [CascadingParameter]
    private WorkflowTab? Parent { get; set; }

    private GXWorkflow? _active;

    private GXWorkflow? Active
    {
        get
        {
            if (Parent?.Active != null)
            {
                return Parent.Active;
            }
            return _active;
        }
    }

    /// <summary>
    /// User action.
    /// </summary>
    [Parameter]
    public string? Action { get; set; }

    private CrudAction action;
    /// <summary>
    /// Selected item.
    /// </summary>
    [Parameter]
    public Guid? Id { get; set; }

    private bool DeleteTarget;
    public string? IsDeleting
    {
        get
        {
            if (Notifier.Action != CrudAction.Delete)
            {
                return null;
            }
            return "disabled";
        }
    }

    GXTrigger Trigger
    {
        get;
        set;
    }

    private string? _selectedTrigger;

    string? SelectedTrigger
    {
        get
        {
            return _selectedTrigger;
        }
        set
        {
            _selectedTrigger = value;
            StateHasChanged();
        }
    }

    ///Update trigger condition script.
    string? SelectedCondition
    {
        get
        {
            if (Active?.TriggerMethod == null)
            {
                return null;
            }

            return Active.TriggerMethod.Name;
        }
        set
        {
            if (Active != null && _scriptMethods != null)
            {
                if (string.IsNullOrEmpty(value))
                {
                    Active.TriggerMethod = null;
                }
                else
                {
                    foreach (var method in _scriptMethods)
                    {
                        if (string.Compare(method.Name, value, true) == 0)
                        {
                            Active.TriggerMethod = method;
                            break;
                        }
                    }
                    StateHasChanged();
                }
            }
        }
    }

    string? SelectedActivity
    {
        get
        {
            return Active?.TriggerActivity?.Name;
        }
        set
        {
            foreach (var trigger in triggers)
            {
                if (string.Compare(trigger.ClassName, SelectedTrigger, true) == 0)
                {
                    foreach (var activity in trigger.Activities)
                    {
                        if (string.Compare(activity.Name, value, true) == 0)
                        {
                            activity.Trigger = trigger;
                            Active.TriggerActivity = activity;
                            break;
                        }
                    }
                    break;
                }
            }
            StateHasChanged();
        }
    }

    List<GXTriggerActivity> Activities
    {
        get
        {
            foreach (var it in triggers)
            {
                if (it.ClassName == SelectedTrigger)
                {
                    return it.Activities;
                }
            }
            return new List<GXTriggerActivity>();
        }
    }

    GXTrigger[]? triggers = null;
    private GXScriptMethod[]? _scriptMethods = null;

    protected override async Task OnInitializedAsync()
    {
        try
        {
            Notifier.ProgressStart();
            Notifier.ClearStatus();
            Notifier.Clear();
            if (Active == null && Id != null)
            {
                //Get workflow data.
                var tmp = (await Http.GetAsJsonAsync<GetWorkflowResponse>(string.Format("api/Workflow?id={0}", Id)));
                if (tmp?.Item != null)
                {
                    _active = tmp.Item;
                }
                else
                {
                    NavigationManager.NavigateTo("404");
                }
            }
            if (Active == null)
            {
                throw new ArgumentException(Properties.Resources.InvalidTarget);
            }
            action = ClientHelpers.GetAction(Action);
            if (action == CrudAction.Delete)
            {
                Notifier.AddMenuItem(new GXMenuItem() { Text = Properties.Resources.Remove, Icon = "oi oi-trash", OnClick = OnSave });
            }
            else
            {
                Notifier.AddMenuItem(new GXMenuItem() { Text = Properties.Resources.Save, Icon = "oi oi-pencil", OnClick = OnSave });
            }
            Notifier.AddMenuItem(new GXMenuItem() { Text = Properties.Resources.Cancel, Icon = "oi oi-action-undo", OnClick = OnCancel });
            Notifier.UpdateButtons();

            //Get available script methods.
            ListScripts req1 = new ListScripts();
            var ret1 = await Http.PostAsJson<ListScriptsResponse>("api/Script/List", req1);
            _scriptMethods = null;
            if (ret1.Scripts != null && ret1.Scripts.Any())
            {
                List<GXScriptMethod> methods = new List<GXScriptMethod>();
                //Add empty script method.
                methods.Add(new GXScriptMethod() { });
                foreach (var script in ret1.Scripts)
                {
                    foreach (var method in script.Methods)
                    {
                        if (method.Function)
                        {
                            methods.Add(method);
                        }
                    }

                }
                _scriptMethods = methods.ToArray();
            }
            //Get triggers.
            ListTriggers req = new ListTriggers();
            var ret = await Http.PostAsJson<ListTriggersResponse>("api/Trigger/List", req);
            triggers = ret.Triggers;
            if (action == CrudAction.Create && triggers != null && triggers.Any() && Active.TriggerActivity == null)
            {
                //Select first item if trigger is not selected.
                if (triggers[0].Activities != null && triggers[0].Activities.Any())
                {
                    Active.TriggerActivity = triggers[0].Activities[0];
                    Active.TriggerActivity.Trigger = triggers[0];
                }
            }
            SelectedTrigger = Active?.TriggerActivity?.Trigger?.ClassName;
            SelectedCondition = Active?.TriggerMethod?.Name;
        }
        catch (AccessTokenNotAvailableException exception)
        {
            exception.Redirect();
        }
        catch (Exception ex)
        {
            Notifier?.ProcessError(ex);
        }
        finally
        {
            Notifier?.ProgressEnd();
        }
    }

    /// <summary>
    /// Save workflow.
    /// </summary>
    public async void OnSave()
    {
        try
        {
            if (Active == null)
            {
                throw new Exception(Properties.Resources.InvalidTarget);
            }
            Notifier.ProgressStart();
            Notifier.ClearStatus();
            //Object cycle is removed.
            if (Active.TriggerActivity != null)
            {
                Active.TriggerActivity.Trigger = null;
            }
            if (Active.ScriptMethods != null)
            {
                foreach (GXScriptMethod method in Active.ScriptMethods)
                {
                    //Reset parent.
                    method.Script = null;
                }
            }
            if (action == CrudAction.Delete)
            {
                await Http.PostAsJson<RemoveWorkflowResponse>("api/Workflow/Delete", new RemoveWorkflow()
                    {
                        Ids = new Guid[] { Active.Id },
                        Delete = DeleteTarget
                    });
            }
            else
            {
                string address;
                if (action == CrudAction.Create)
                {
                    address = "api/Workflow/Add";
                }
                else if (action == CrudAction.Update)
                {
                    address = "api/Workflow/Update";
                }
                else
                {
                    throw new Exception(Properties.Resources.InvalidTarget);
                }
                await Http.PostAsJson<UpdateWorkflowResponse>(address, new UpdateWorkflow() { Workflows = new GXWorkflow[] { Active } });
            }
            ClientHelpers.NavigateToLastPage(NavigationManager, Notifier);
        }
        catch (AccessTokenNotAvailableException exception)
        {
            exception.Redirect();
        }
        catch (Exception ex)
        {
            Notifier?.ProcessError(ex);
        }
        finally
        {
            Notifier?.ProgressEnd();
        }
    }

    /// <summary>
    /// Cancel update.
    /// </summary>
    private void OnCancel()
    {
        ClientHelpers.NavigateToLastPage(NavigationManager, Notifier);
    }
}
